package io.itit.ecp.admin.provide.action.controller.miniprogram;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import icu.mhb.mybatisplus.plugln.extend.Joins;
import io.itit.ecp.admin.common.enums.IMeterDeviceEnums;
import io.itit.ecp.admin.server.entity.CarbonEmissionRangeEntity;
import io.itit.ecp.admin.server.entity.EnergyDataEntity;
import io.itit.ecp.admin.server.entity.MeterDeviceEntity;
import io.itit.ecp.admin.server.service.ICarbonEmissionRangeService;
import io.itit.grass.common.provide.action.resp.ResultResp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 小程序碳排放
 */
@Api(tags = "小程序碳排放管理")
@RestController
@RequestMapping("/mini/carbonEmission")
public class MiniCarbonEmissionController {

    @Resource
    private ICarbonEmissionRangeService carbonEmissionRangeService;

    /**
     * 碳排放数据
     */
    @GetMapping("total")
    @ApiOperation("碳排放数据")
    public ResultResp<Map<String, Object>> getTotal(@RequestParam(required = false) String sceneProjectId,
                                                    @RequestParam(required = false) String sceneEdificeId,
                                                    @RequestParam(required = false) String sceneFloorId,
                                                    @RequestParam(required = false) String startTime,
                                                    @RequestParam(required = false) String endTime) {
        LocalDateTime start = StringUtils.hasLength(startTime) ? LocalDate.parse(startTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MIN) : null;
        LocalDateTime end = StringUtils.hasLength(endTime) ? LocalDate.parse(endTime, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atTime(LocalTime.MAX) : LocalDateTime.now();
        BigDecimal t = new BigDecimal("1000");
        List<EnergyDataEntity> list = Joins.of(EnergyDataEntity.class)
                .selectAs(builder -> {
                    builder.add("ecp_tt_energy_data.calculation_range", "calculationRange", false);
                    builder.add("SUM(ecp_tt_energy_data.carbon_emission)", "carbonEmission", false);
                })
                .leftJoin(MeterDeviceEntity.class, MeterDeviceEntity::getId, EnergyDataEntity::getMeterDeviceId)
                .notIn(MeterDeviceEntity::getReadMeterType, IMeterDeviceEnums.ReadMeterType.getZeroCarbonList())
                .end()
                .eq(org.apache.commons.lang3.StringUtils.isNotEmpty(sceneProjectId), EnergyDataEntity::getSceneProjectId, sceneProjectId)
                .eq(org.apache.commons.lang3.StringUtils.isNotEmpty(sceneEdificeId), EnergyDataEntity::getSceneEdificeId, sceneEdificeId)
                .eq(org.apache.commons.lang3.StringUtils.isNotEmpty(sceneFloorId), EnergyDataEntity::getSceneFloorId, sceneFloorId)
                .ge(Objects.nonNull(start), EnergyDataEntity::getSolidifyDate, start)
                .le(EnergyDataEntity::getSolidifyDate, end)
                .groupBy(EnergyDataEntity::getCalculationRange).joinList(EnergyDataEntity.class);
        List<CarbonEmissionRangeEntity> rangeEntities = carbonEmissionRangeService
                .list(new LambdaQueryWrapper<CarbonEmissionRangeEntity>().orderByAsc(CarbonEmissionRangeEntity::getRangeName));
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> rangeList = new ArrayList<>();
        BigDecimal total = list.stream().map(EnergyDataEntity::getCarbonEmission).filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, RoundingMode.HALF_DOWN);
        String unit = "kgCO2";

        for (CarbonEmissionRangeEntity rangeEntity : rangeEntities) {
            Map<String, Object> range = new HashMap<>();
            range.put("name", rangeEntity.getRangeName());
            range.put("value", list.stream()
                    .filter(item -> org.apache.commons.lang3.StringUtils.equals(item.getCalculationRange(), rangeEntity.getId()))
                    .findFirst()
                    .map(EnergyDataEntity::getCarbonEmission)
                    .orElse(BigDecimal.ZERO).setScale(2, RoundingMode.HALF_DOWN));
            rangeList.add(range);
        }

        if (total.compareTo(t) >= 0 || rangeList.stream().anyMatch(item -> ((BigDecimal) item.get("value")).compareTo(t) >= 0)) {
            unit = "tCO2";
            total = total.divide(t, 2, RoundingMode.HALF_DOWN);
            for (Map<String, Object> item : rangeList) {
                item.put("value", ((BigDecimal) item.get("value")).divide(t, 2, RoundingMode.HALF_DOWN));
            }
        }
        result.put("total", total);
        result.put("unit", unit);
        result.put("rangeList", rangeList);
        return ResultResp.success(result);
    }
}
